Indexing and selecting Data

In [1]:
#Import Library
import pandas as pd
import numpy as np
In [2]:
#To generate random number, we import randn from numpy.
from numpy.random import randn
np.random.seed(101)
In [3]:
#Create Dataframe
df = pd.DataFrame(randn(5,4),index='A B C D E'.split(),columns='W X Y Z'.split()) #Split will seperate the column
In [5]:
df
Out[5]:
W X Y Z
A 2.706850 0.628133 0.907969 0.503826
B 0.651118 -0.319318 -0.848077 0.605965
C -2.018168 0.740122 0.528813 -0.589001
D 0.188695 -0.758872 -0.933237 0.955057
E 0.190794 1.978757 2.605967 0.683509

Selection and Indexing

Let's learn the various methods to grab data from a DataFrame

In [8]:
#Select W column
df['W']
Out[8]:
A    2.706850
B    0.651118
C   -2.018168
D    0.188695
E    0.190794
Name: W, dtype: float64
In [9]:
# Pass a list of column names
df[['W','Z']]
Out[9]:
W Z
A 2.706850 0.503826
B 0.651118 0.605965
C -2.018168 -0.589001
D 0.188695 0.955057
E 0.190794 0.683509

DataFrame Columns are just Series

In [10]:
type(df['W'])
Out[10]:
pandas.core.series.Series

Creating a new column:

In [11]:
df['new'] = df['W'] + df['Y']
In [12]:
df
Out[12]:
W X Y Z new
A 2.706850 0.628133 0.907969 0.503826 3.614819
B 0.651118 -0.319318 -0.848077 0.605965 -0.196959
C -2.018168 0.740122 0.528813 -0.589001 -1.489355
D 0.188695 -0.758872 -0.933237 0.955057 -0.744542
E 0.190794 1.978757 2.605967 0.683509 2.796762

Removing Columns

In [13]:
df.drop('new',axis=1)
Out[13]:
W X Y Z
A 2.706850 0.628133 0.907969 0.503826
B 0.651118 -0.319318 -0.848077 0.605965
C -2.018168 0.740122 0.528813 -0.589001
D 0.188695 -0.758872 -0.933237 0.955057
E 0.190794 1.978757 2.605967 0.683509
In [14]:
# Not inplace unless specified!
df
Out[14]:
W X Y Z new
A 2.706850 0.628133 0.907969 0.503826 3.614819
B 0.651118 -0.319318 -0.848077 0.605965 -0.196959
C -2.018168 0.740122 0.528813 -0.589001 -1.489355
D 0.188695 -0.758872 -0.933237 0.955057 -0.744542
E 0.190794 1.978757 2.605967 0.683509 2.796762

So you can see above we have droped new column but it still in our dataframe because we have not mentationed the inplace.

In [15]:
df.drop('new',axis=1,inplace=True)
In [16]:
df
Out[16]:
W X Y Z
A 2.706850 0.628133 0.907969 0.503826
B 0.651118 -0.319318 -0.848077 0.605965
C -2.018168 0.740122 0.528813 -0.589001
D 0.188695 -0.758872 -0.933237 0.955057
E 0.190794 1.978757 2.605967 0.683509

Can also drop rows this way:

In [17]:
df.drop('E',axis=0)
Out[17]:
W X Y Z
A 2.706850 0.628133 0.907969 0.503826
B 0.651118 -0.319318 -0.848077 0.605965
C -2.018168 0.740122 0.528813 -0.589001
D 0.188695 -0.758872 -0.933237 0.955057

Selecting Rows

In [18]:
df.loc['A']
Out[18]:
W    2.706850
X    0.628133
Y    0.907969
Z    0.503826
Name: A, dtype: float64

Or select based off of position instead of label

In [19]:
df.iloc[2]
Out[19]:
W   -2.018168
X    0.740122
Y    0.528813
Z   -0.589001
Name: C, dtype: float64

Selecting subset of rows and columns

In [20]:
df.loc['B','Y']
Out[20]:
-0.8480769834036315
In [21]:
df.loc[['A','B'],['W','Y']]
Out[21]:
W Y
A 2.706850 0.907969
B 0.651118 -0.848077

Conditional Selection

An important feature of pandas is conditional selection using bracket notation, very similar to numpy:

In [22]:
df
Out[22]:
W X Y Z
A 2.706850 0.628133 0.907969 0.503826
B 0.651118 -0.319318 -0.848077 0.605965
C -2.018168 0.740122 0.528813 -0.589001
D 0.188695 -0.758872 -0.933237 0.955057
E 0.190794 1.978757 2.605967 0.683509
In [23]:
#if your condituion is not in [] then it will give you true and false.
# Those who full-fill condition they are true and rest false.
df>0
Out[23]:
W X Y Z
A True True True True
B True False False True
C False True True False
D True False False True
E True True True True
In [26]:
df[df>0]
Out[26]:
W X Y Z
A 2.706850 0.628133 0.907969 0.503826
B 0.651118 NaN NaN 0.605965
C NaN 0.740122 0.528813 NaN
D 0.188695 NaN NaN 0.955057
E 0.190794 1.978757 2.605967 0.683509
In [27]:
df[df['W']>0]
Out[27]:
W X Y Z
A 2.706850 0.628133 0.907969 0.503826
B 0.651118 -0.319318 -0.848077 0.605965
D 0.188695 -0.758872 -0.933237 0.955057
E 0.190794 1.978757 2.605967 0.683509
In [28]:
df[df['W']>0]['Y']
Out[28]:
A    0.907969
B   -0.848077
D   -0.933237
E    2.605967
Name: Y, dtype: float64
In [29]:
df[df['W']>0][['Y','X']]
Out[29]:
Y X
A 0.907969 0.628133
B -0.848077 -0.319318
D -0.933237 -0.758872
E 2.605967 1.978757

For two conditions you can use | and & with parenthesis:

In [208]:
#Only display those values that satisfies both condition
df[(df['W']>0) & (df['Y'] > 1)]
Out[208]:
W X Y Z
E 0.190794 1.978757 2.605967 0.683509
In [30]:
#Display those values who satisfies either one condition
df[(df['W']>0) | (df['Y'] > 1)]
Out[30]:
W X Y Z
A 2.706850 0.628133 0.907969 0.503826
B 0.651118 -0.319318 -0.848077 0.605965
D 0.188695 -0.758872 -0.933237 0.955057
E 0.190794 1.978757 2.605967 0.683509

More Index Details

Let's discuss some more features of indexing, including resetting the index or setting it something else. We'll also talk about index hierarchy!

In [31]:
df
Out[31]:
W X Y Z
A 2.706850 0.628133 0.907969 0.503826
B 0.651118 -0.319318 -0.848077 0.605965
C -2.018168 0.740122 0.528813 -0.589001
D 0.188695 -0.758872 -0.933237 0.955057
E 0.190794 1.978757 2.605967 0.683509
In [32]:
# Reset to default 0,1...n index
df.reset_index()
Out[32]:
index W X Y Z
0 A 2.706850 0.628133 0.907969 0.503826
1 B 0.651118 -0.319318 -0.848077 0.605965
2 C -2.018168 0.740122 0.528813 -0.589001
3 D 0.188695 -0.758872 -0.933237 0.955057
4 E 0.190794 1.978757 2.605967 0.683509
In [33]:
#Define a new index
newind = 'CA NY WY OR CO'.split()
In [34]:
#Define a new column called state and assign newind to it
df['States'] = newind
In [35]:
df
Out[35]:
W X Y Z States
A 2.706850 0.628133 0.907969 0.503826 CA
B 0.651118 -0.319318 -0.848077 0.605965 NY
C -2.018168 0.740122 0.528813 -0.589001 WY
D 0.188695 -0.758872 -0.933237 0.955057 OR
E 0.190794 1.978757 2.605967 0.683509 CO
In [36]:
df.set_index('States')
Out[36]:
W X Y Z
States
CA 2.706850 0.628133 0.907969 0.503826
NY 0.651118 -0.319318 -0.848077 0.605965
WY -2.018168 0.740122 0.528813 -0.589001
OR 0.188695 -0.758872 -0.933237 0.955057
CO 0.190794 1.978757 2.605967 0.683509
In [37]:
df
Out[37]:
W X Y Z States
A 2.706850 0.628133 0.907969 0.503826 CA
B 0.651118 -0.319318 -0.848077 0.605965 NY
C -2.018168 0.740122 0.528813 -0.589001 WY
D 0.188695 -0.758872 -0.933237 0.955057 OR
E 0.190794 1.978757 2.605967 0.683509 CO
In [38]:
#Set state as index
df.set_index('States',inplace=True)
In [39]:
df
Out[39]:
W X Y Z
States
CA 2.706850 0.628133 0.907969 0.503826
NY 0.651118 -0.319318 -0.848077 0.605965
WY -2.018168 0.740122 0.528813 -0.589001
OR 0.188695 -0.758872 -0.933237 0.955057
CO 0.190794 1.978757 2.605967 0.683509

Multi-Index and Index Hierarchy

Let us go over how to work with Multi-Index, first we'll create a quick example of what a Multi-Indexed DataFrame would look like:

In [43]:
# Index Levels
outside = ['G1','G1','G1','G2','G2','G2']
inside = [1,2,3,1,2,3]
hier_index = list(zip(outside,inside))#zip function is use to club the list
hier_index = pd.MultiIndex.from_tuples(hier_index)
In [44]:
hier_index
Out[44]:
MultiIndex(levels=[['G1', 'G2'], [1, 2, 3]],
           labels=[[0, 0, 0, 1, 1, 1], [0, 1, 2, 0, 1, 2]])
In [45]:
#Convert into dataframe
df = pd.DataFrame(np.random.randn(6,2),index=hier_index,columns=['A','B'])
df
Out[45]:
A B
G1 1 0.302665 1.693723
2 -1.706086 -1.159119
3 -0.134841 0.390528
G2 1 0.166905 0.184502
2 0.807706 0.072960
3 0.638787 0.329646

Now let's show how to index this! For index hierarchy we use df.loc[], if this was on the columns axis, you would just use normal bracket notation df[]. Calling one level of the index returns the sub-dataframe:

In [46]:
# We can select G1 data
df.loc['G1']
Out[46]:
A B
1 0.302665 1.693723
2 -1.706086 -1.159119
3 -0.134841 0.390528
In [47]:
df.loc['G1'].loc[1]
Out[47]:
A    0.302665
B    1.693723
Name: 1, dtype: float64
In [48]:
df.index.names
Out[48]:
FrozenList([None, None])
In [49]:
#Define index name
df.index.names = ['Group','Num']
In [51]:
df
Out[51]:
A B
Group Num
G1 1 0.302665 1.693723
2 -1.706086 -1.159119
3 -0.134841 0.390528
G2 1 0.166905 0.184502
2 0.807706 0.072960
3 0.638787 0.329646
In [52]:
df.xs('G1')
Out[52]:
A B
Num
1 0.302665 1.693723
2 -1.706086 -1.159119
3 -0.134841 0.390528
In [53]:
df.xs(['G1',1])
Out[53]:
A    0.302665
B    1.693723
Name: (G1, 1), dtype: float64
In [54]:
df.xs(1,level='Num')
Out[54]:
A B
Group
G1 0.302665 1.693723
G2 0.166905 0.184502